#include "head.h"
int sendfd(int sockfd,int fdtosend)
{
    // 将父进程监听得到的netfd发送给子进程 
    struct msghdr hdr;
    //确保msghdr中的 name->NULL ,namelen->0 不可忽略
    bzero(&hdr,sizeof(hdr));
    //无论正文部分在业务中是否有用，必须要有正文
    char buf[] = "hello";
    struct iovec vec[1];//数组记录离散区域
    vec[0].iov_base = buf;
    vec[0].iov_len = 5;
    hdr.msg_iov = vec;// 将离散区域的信息放入到hdr中
    hdr.msg_iovlen = 1;
    //控制字段部分，记录要发送的内核数据结构
    struct cmsghdr * pcmsg = (struct cmsghdr *)malloc( /*data:fd -- > int*/CMSG_LEN(sizeof(int)));
    pcmsg->cmsg_len = CMSG_LEN(sizeof(int));//结构体长度
    pcmsg->cmsg_level = SOL_SOCKET;//选择的协议
    pcmsg->cmsg_type = SCM_RIGHTS;//类型：即发送的文件对象
    // 通过pcmsg得到data首地址，强转成int*，再解引用
    *(int *)CMSG_DATA(pcmsg) = fdtosend;//发送的数据
    hdr.msg_control = pcmsg;
    hdr.msg_controllen = CMSG_LEN(sizeof(int));
    int ret = sendmsg(sockfd,&hdr,0);//把文件对象发送给子进程
    ERROR_CHECK(ret,-1,"sendmsg");
    return 0;

}
int recvfd(int sockfd,int *pfdtorecv)
{
    // 接收父进程发送的数据结构
    // 接收和发送的区别，接收方不知道buf和pcmsg->data的内容
    struct msghdr hdr;
    //确保msghdr中的 name->NULL ,namelen->0 不可忽略
    bzero(&hdr,sizeof(hdr));
    //无论正文部分在业务中是否有用，必须要有正文
    char buf[6] = {0};//正文数据
    struct iovec vec[1];//数组记录离散区域
    vec[0].iov_base = buf;
    vec[0].iov_len = 5;
    hdr.msg_iov = vec;// 将离散区域的信息放入到hdr中
    hdr.msg_iovlen = 1;
    //控制字段部分，记录要发送的内核数据结构
    struct cmsghdr * pcmsg = (struct cmsghdr *)malloc( /*data:fd -- > int*/CMSG_LEN(sizeof(int)));
    pcmsg->cmsg_len = CMSG_LEN(sizeof(int));//结构体长度
    pcmsg->cmsg_level = SOL_SOCKET;//选择的协议
    pcmsg->cmsg_type = SCM_RIGHTS;//类型：即发送的文件对象
    hdr.msg_control = pcmsg;
    hdr.msg_controllen = CMSG_LEN(sizeof(int));
    int ret = recvmsg(sockfd,&hdr,0);//把文件对象发送给子进程
    ERROR_CHECK(ret,-1,"recvmsg");
    printf("buf = %s,fd = %d\n",buf,
        *(int *)CMSG_DATA(pcmsg));
    *pfdtorecv = *(int *)CMSG_DATA(pcmsg);
    return 0;
    
}
